﻿using System.Collections.Generic;
using System.Linq;

namespace Core
{
    public class SimpleWordFinder : IWordFinder
    {
        public event WordFinderDelegates.WordFound OnWordFound = delegate { };
        public event WordFinderDelegates.WordsFound OnFinished = delegate { };

        private readonly Board _board;
        private readonly Wordlist _wordlist;
        private readonly List<List<int>> _foundwords;

        public SimpleWordFinder(Board board, Wordlist wordlist)
        {
            _board = board;
            _wordlist = wordlist;
            _foundwords = new List<List<int>>();
        }

        public void FindAllWords()
        {
            for (int i = 0; i < _board.AllTiles.Count; i++)
            {
                Recurse(i, new List<int> { i });
            }
            OnFinished(_foundwords);
        }

        private void Recurse(int tileIndex, List<int> moveHistory)
        {
            if (moveHistory.Count <= 2)
            {
                foreach (int i in _board.LeftoverMoves(tileIndex, moveHistory))
                {
                    Recurse(i, new List<int>(moveHistory) { i });
                }
                return;
            }

            // what are we searching on?
            var search = _board.MovesToWord(moveHistory);

            // leftover moves for this position
            var leftOverMoves = _board.LeftoverMoves(tileIndex, moveHistory);
            if (leftOverMoves.Count > 0)
            {
                // what valid moves are next?
                var validMoves = _wordlist.ValidMovesFor(search);

                // iterate all of the leftover moves to see if any are valid
                foreach (int i in leftOverMoves)
                {
                    if (validMoves.Contains(_board.AllTiles[i].Character))
                    {
                        //need to continue recursing
                        Recurse(i, new List<int>(moveHistory) { i });
                    }
                }
            }

            // is this a word in its own right?
            if (_wordlist.IsWholeWord(search))
            {
                _foundwords.Add(moveHistory);
                OnWordFound(moveHistory);
            }
        }
    }
}